/*
 * TowerUpgradeDamage.java
 *
 * Created on January 15, 2008, 7:56 PM
 *
 * Copyright (C) 2007-2008  Hylke van der Schaaf
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, in version 3 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

package hextd.tower;

import hextd.hex.Hex;
import hextd.util.Context;
import hextd.util.TowerListener;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.Line2D;
import java.util.Iterator;
import java.util.Vector;
import javax.swing.JPanel;

/**
 *
 * @author hylke
 */
public class TowerUpgradeDamage extends TowerBase implements TowerListener {
    
    public static int price = 0;
    public static int damage = 0;
    public static float range = 4.3f;
    
    private Vector<Tower>   clients;
    private Line2D[]        clientLines;
    private Stroke          clientStroke;
    private Color           clientColor;
    
    /** Creates a new instance of TowerUpgradeDamage */
    public TowerUpgradeDamage(Context context, Hex hex) {
        super(TowerFactory.type.upgradeDamage, price, damage, range);
        
        this.lineColor = new Color(200, 200, 200);
        this.clientColor = new Color(255, 50, 50);
        this.clients = new Vector<Tower>();
        
        this.doInit(context, hex);
        this.pts = null;
        context.loadSvg("upgradeDamage", "images/upgradeDamage.svg");
        
        this.context.addTowerListener(this);
        
        this.scanTowers();
    }
    
    private void scanTowers() {
        if (!this.selling) {
            Tower t;
            float dx,dy;
            float[] loc;
            for (Iterator<Tower> i=this.context.towers.iterator(); i.hasNext();) {
                t = i.next();
                if (!this.clients.contains(t)) {
                    switch (t.getType()) {
                        case firecontrol:
                        case upgradeDamage:
                        case upgradeRange:
                            break;
                        default:
                            loc = t.getHex().getFloatLocation();
                            dx = this.xFloat-loc[0];
                            dy = this.yFloat-loc[1];
                            if ( (dx*dx+dy*dy) < this.rangeCurrent2 ) {
                                t.registerTower(this);
                            }
                            break;
                    }
                } else {
                    loc = t.getHex().getFloatLocation();
                    dx = this.xFloat-loc[0];
                    dy = this.yFloat-loc[1];
                    if ( (dx*dx+dy*dy) > this.rangeCurrent2 ) {
                        t.unregisterTower(this);
                    }
                }
            }
        }
    }
    
    protected void calcDamageRange() {
        super.calcDamageRange();
        this.scanTowers();
    }
    
    public boolean canUpgrade() {
        return false;
    }
    
    public String getStatusString() {
        String retString = "";
        retString += "<h1>Damage Upgrade</h1>" +
                "<p>" +
                "Increases the damage of other towers.<br>" +
                "<b>Towers affected:</b> "+this.clients.size()+"<br>\n" +
                "<b>Range:</b> "+this.rangeText+"<br>" +
                "</p>\n";
        return retString;
    }
    
    public String getInfoString() {
        String retString = "";
        retString += "<h1>Damage Upgrade</h1>" +
                "<p>Increases the damage of other towers.</p>" +
                "<p class='warn'>This tower costs 1 bonus point.</p>";
        return retString;
    }
    
    public void doTick(int gameTime) {
    }
    
    public void towerBuild(Tower t) {
        if (t != this && !this.selling && !this.clients.contains(t)) {
            switch (t.getType()) {
                case firecontrol:
                case upgradeDamage:
                case upgradeRange:
                    break;
                default:
                    float dx,dy;
                    float[] loc;
                    loc = t.getHex().getFloatLocation();
                    dx = this.xFloat-loc[0];
                    dy = this.yFloat-loc[1];
                    if ( (dx*dx+dy*dy) < this.rangeCurrent2 ) {
                        t.registerTower(this);
                    }
                    break;
            }
        }
    }
    public void towerRemoved(Tower t) {
        if (this.clients.contains(t)) {
            t.unregisterTower(this);
        }
    }
    
    public void addClient(Tower t) {
        if (!this.selling && !this.clients.contains(t)) {
            this.clients.add(t);
            this.generateShapes();
        }
    }
    public void removeClient(Tower t) {
        this.clients.remove(t);
        this.generateShapes();
    }
    
    public void doCleanup() {
        super.doCleanup();
        for (int i=this.clients.size()-1; i>=0; i--) {
            Tower t = this.clients.get(i);
            t.unregisterTower(this);
        }
        this.context.removeTowerListener(this);
    }
    
    public String getSvgName() {
        return "upgradeDamage";
    }
    
    void generateShapes() {
        float cx = +0;
        float cy = +this.paintScale/3;
        
        this.shapes = new Shape[0];
        
        this.clientLines = new Line2D[this.clients.size()];
        float[] from;
        float[] to = this.getHex().getPaintLocation();
        to[0] += cx;
        to[1] += cy;
        for (int i=0; i<this.clientLines.length; i++) {
            from = this.clients.get(i).getHex().getPaintLocation();
            this.clientLines[i] = new Line2D.Float(from[0], from[1], to[0], to[1]);
        }
        this.clientStroke = new BasicStroke(1.0f*this.context.strokeScale, BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL);
    }
    
    public void paintEffects(Graphics2D g2, int gameTime) {
        g2.setStroke(this.clientStroke);
        g2.setColor(this.clientColor);
        for (int i=0; i<this.clientLines.length; i++) {
            g2.draw(this.clientLines[i]);
        }
    }
    
}
